import { RuntimeError } from '@ibiz-template/core';
import {
  ControlController,
  IWizardPanelState,
  IWizardPanelEvent,
  IWizardPanelController,
  IControlProvider,
  getControlProvider,
  EventBase,
  calcDeCodeNameById,
} from '@ibiz-template/runtime';
import {
  IDEWizardEditForm,
  IDEWizardForm,
  IDEWizardPanel,
} from '@ibiz/model-core';
import { EditFormController } from '../form';
import { WizardPanelService } from './wizard-panel.service';

/**
 * 向导面板控制器
 *
 * @author chitanda
 * @date 2022-07-24 15:07:07
 * @export
 * @class WizardPanelController
 * @extends {ControlController}
 */
export class WizardPanelController
  extends ControlController<
    IDEWizardPanel,
    IWizardPanelState,
    IWizardPanelEvent
  >
  implements IWizardPanelController
{
  /**
   * 编辑表单服务
   * @author lxm
   * @date 2023-05-15 11:03:34
   * @type {WizardPanelService}
   */
  service!: WizardPanelService;

  /**
   * 表单标识历史
   *
   * @author lxm
   * @date 2023-02-16 08:41:35
   * @type {string[]}
   * @memberof WizardPanelController
   */
  tagHistory: string[] = [];

  /**
   * 所有部件的适配器
   *
   * @author lxm
   * @date 2022-08-24 20:08:07
   * @type {{ [key: string]: IControlProvider }}
   */
  providers: { [key: string]: IControlProvider } = {};

  /**
   * 首表单模型
   * @return {*}
   * @author: zhujiamin
   * @Date: 2023-06-07 15:03:39
   */
  firstForm: IDEWizardForm | undefined = undefined;

  /**
   * 所有表单控制器Map
   * @return {*}
   * @author: zhujiamin
   * @Date: 2023-06-07 15:13:21
   */
  formControllers: Map<string, EditFormController> = new Map();

  /**
   * 步骤集合
   * @return {*}
   * @author: zhujiamin
   * @Date: 2023-06-07 15:13:21
   */
  steps: string[] = [];

  /**
   * 步骤标识集合
   * @return {*}
   * @author: zhujiamin
   * @Date: 2023-06-07 15:13:21
   */
  stepTags: IData = {};

  protected initState(): void {
    super.initState();
  }

  protected async onCreated(): Promise<void> {
    await super.onCreated();

    this.model.dewizard!.dewizardForms!.forEach((wizardForm: IDEWizardForm) => {
      // 首表单
      if (wizardForm.firstForm) {
        this.firstForm = wizardForm;
      }
      // 步骤标识
      const formName = `${
        this.model.name
      }_form_${wizardForm.formTag?.toLowerCase()}`;
      const wizardStep = this.model.dewizard?.dewizardSteps?.find(step => {
        return step.id === wizardForm.dewizardStepId;
      });
      const stepTag = wizardStep?.stepTag;
      this.stepTags[formName] = stepTag;
    });

    // 步骤集合
    this.model.dewizard?.dewizardSteps?.forEach(step => {
      this.steps.push(step.stepTag!);
    });
    // 实例部件服务
    this.service = new WizardPanelService(this.model);
    await this.service.init(this.context);
    // 编辑表单适配器
    const { deeditForms } = this.model;
    if (deeditForms && deeditForms.length > 0) {
      await Promise.all(
        deeditForms.map(async editForm => {
          const formTag = (editForm as IDEWizardEditForm).dewizardForm!.formTag;
          if (formTag) {
            const provider = await getControlProvider(editForm);
            if (provider) {
              this.providers[formTag] = provider;
            }
          }
        }),
      );
    }
  }

  /**
   * 当前激活的向导表单
   *
   * @author lxm
   * @date 2023-02-17 10:42:06
   * @readonly
   * @memberof WizardPanelController
   */
  get activeWizardForm(): IDEWizardForm | undefined {
    const { activeFormTag } = this.state;
    const form = this.model.dewizard!.dewizardForms!.find(
      (wizardForm: IDEWizardForm) => {
        return wizardForm.formTag === activeFormTag;
      },
    );
    if (!form) {
      ibiz.log.debug(`找不到${activeFormTag}的向导表单`);
    }
    return form;
  }

  /**
   * 当前激活向导表单的控制器
   *
   * @author lxm
   * @date 2023-02-17 03:44:46
   * @readonly
   * @memberof WizardPanelController
   */
  get activeFormController(): EditFormController {
    const { activeFormTag } = this.state;
    const controller = this.formControllers.get(activeFormTag);
    if (!controller) {
      throw new RuntimeError(`找不到${activeFormTag}的表单控制器`);
    }
    return controller;
  }

  /**
   * 表单挂载后把控制器抛出来
   * @param {string} activeFormTag
   * @return {*}
   * @author: zhujiamin
   * @Date: 2023-06-07 15:14:05
   */
  onFormMounted(activeFormTag: string, event: EventBase): void {
    const formController = event.ctrl as EditFormController;
    this.formControllers.set(activeFormTag, formController);
    // 调用表单的load加载一次数据
    formController.load();
  }

  /**
   * 表单保存后，如果上下文里没有主键，赋予主键
   * @param {EventBase} event
   * @return {*}
   * @author: zhujiamin
   * @Date: 2023-06-08 14:06:25
   */
  onFormSaved(event: EventBase): void {
    const data = event.data[0];
    const deName = calcDeCodeNameById(this.model.appDataEntityId!);
    if (!this.context[deName] && data && data.srfkey) {
      this.context[deName] = data.srfkey;
    }
  }

  /**
   * 执行初始化操作，存在初始化实体行为的时候加载数据并把主键放入上下文
   *
   * @author lxm
   * @date 2022-08-19 14:08:50
   */
  async initialize(): Promise<void> {
    const initAction = this.model.initControlAction?.appDEMethodId;
    if (initAction) {
      const res = await this.service.initialize(this.context, this.params);
      const deName = calcDeCodeNameById(this.model.appDataEntityId!);
      if (res.data && res.data.srfkey) {
        this.context[deName] = res.data.srfkey;
      }
    }
    if (this.firstForm) {
      this.state.activeFormTag = this.firstForm.formTag!;
      this.tagHistory.push(this.firstForm.formTag!);
    }
  }

  /**
   * 执行完成操作
   *
   * @author lxm
   * @date 2023-02-16 06:20:18
   * @returns {*}  {Promise<void>}
   * @memberof WizardPanelController
   */
  async finish(): Promise<void> {
    await this.service.finish(this.context, this.params);
    this.evt.emit('onFinishSuccess', undefined);
  }

  /**
   * 处理上一步按钮点击
   *
   * @author lxm
   * @date 2023-02-16 09:10:04
   * @memberof WizardPanelController
   */
  async onPrevClick(): Promise<void> {
    // 先执行表单返回行为
    await this.activeFormController.goBack();
    // 返回上一个表单
    this.tagHistory.pop();
    const prevTag = this.tagHistory[this.tagHistory.length - 1];
    if (!prevTag) {
      throw new RuntimeError('没有上一个表单');
    }
    this.state.activeFormTag = prevTag;
  }

  /**
   * 处理下一步按钮点击
   *
   * @author lxm
   * @date 2023-02-16 09:10:17
   * @memberof WizardPanelController
   */
  async onNextClick(): Promise<void> {
    // 保存
    const data = await this.activeFormController.save();
    let nextTag;
    if (data.srfnextform) {
      const wizardForm = this.model.dewizard!.dewizardForms!.find(
        (_wizardForm: IDEWizardForm) => {
          return _wizardForm.formTag === data.srfnextform;
        },
      );
      if (!wizardForm) {
        throw new RuntimeError(`找不到标识为${data.srfnextform}的向导表单`);
      }
      nextTag = data.srfnextform;
    } else {
      // 通过步骤找,找到下一个步骤对应的第一个向导表单
      const formTag = this.activeWizardForm!.formTag;
      const wizardSteps = this.model.dewizard!.dewizardSteps;
      if (wizardSteps && formTag) {
        const index = wizardSteps.findIndex(_step => {
          return _step.stepTag === formTag;
        });
        const nextWizardStep = wizardSteps[index + 1];
        if (!nextWizardStep) {
          throw new RuntimeError('找不到下一个向导步骤');
        }
        const nextWizardForm = this.model.dewizard!.dewizardForms!.find(
          (wizardForm: IDEWizardForm) => {
            return wizardForm.formTag === nextWizardStep.stepTag;
          },
        );
        if (nextWizardForm) {
          nextTag = nextWizardForm.formTag;
        }
      }
    }
    if (!nextTag) {
      throw new RuntimeError('找不到下一个向导表单');
    }
    this.state.activeFormTag = nextTag;
    this.tagHistory.push(nextTag);
  }

  /**
   * 处理完成按钮点击
   *
   * @author lxm
   * @date 2023-02-16 09:09:45
   * @memberof WizardPanelController
   */
  async onFinishClick(): Promise<void> {
    // 保存
    await this.activeFormController.save();
    await this.finish();
  }
}
